import PikaStdLib
import machine
import os
import _ctest
import aht20
import unittest
import network
import socket
import json
import _thread
import eventloop
import fsm
import PikaDebug
import time
import modbus
import mqtt
import pika_lvgl

pdb = PikaDebug.Debuger()

print('hello PikaPython')
mem = PikaStdLib.MemChecker()
print('mem used max:')
mem.max()
print('mem used now:')
mem.now()


class AHT20UnitTest(unittest.TestCase):
    def test_read(self):
        aht = aht20.AHT20()
        temp, humi = aht.read()
        print('temp: ', temp, ' humi: ', humi)
        self.assertTrue(temp > -40 and temp < 80)
        self.assertTrue(humi > 0 and humi < 100)

    def test_readTemp(self):
        aht = aht20.AHT20()
        temp = aht.readTemp()
        print('temp: ', temp)
        self.assertTrue(temp > -40 and temp < 80)

    def test_readHumidity(self):
        aht = aht20.AHT20()
        humi = aht.readHumidity()
        print('humi: ', humi)
        self.assertTrue(humi > 0 and humi < 100)


def utest():
    suit = unittest.TestSuite("test1")
    suit.addTest(AHT20UnitTest())
    runner = unittest.TextTestRunner()
    res = runner.run(suit)


def wifi_init():
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)
    wlan.connect('CU_ugJz', '16643685017')

    for i in range(10):
        if wlan.isconnected():
            print('wifi connected')
            return
        time.sleep(1)
        print('wifi connecting...', i)


def socket_connect():
    wifi_init()
    pdb.set_trace()
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client.connect(('192.168.1.5', 8080))
    print('socket connected')
    client.send('hello'.encode())
    return client


def aht20_upload():
    client = socket_connect()
    aht = aht20.AHT20()
    temp, humi = aht.read()
    message_dict = {'temp': temp, 'humi': humi}
    message_json = json.dumps(message_dict)
    client.send(message_json.encode())


def aht20_wait_request():
    client = socket_connect()
    while True:
        recv_str = client.recv(1024).decode()
        pdb.set_trace()
        print('recv: ', recv_str)
        if recv_str == 'exit':
            break
        recv_dict = json.loads(recv_str)

        if 'fun' not in recv_dict:
            print('fun not in recv_dict')
            continue

        if recv_dict['fun'] == "request_aht20":
            aht = aht20.AHT20()
            temp, humi = aht.read()
            message_dict = {
                "fun": "response_aht20",
                "ret":  {
                    "temp": temp,
                    "humi": humi
                }
            }
            message_json = json.dumps(message_dict)
            client.send(message_json.encode())


def request_aht20():
    aht = aht20.AHT20()
    temp, humi = aht.read()
    message_dict = {
        "temp": temp,
        "humi": humi
    }
    return message_dict


def request_temp():
    aht = aht20.AHT20()
    temp, humi = aht.read()
    message_dict = {
        "temp": temp
    }
    return message_dict


def request_humi():
    aht = aht20.AHT20()
    temp, humi = aht.read()
    message_dict = {
        "humi": humi
    }
    return message_dict


def aht20_wait_request_eval():
    client = socket_connect()
    while True:
        recv_str = client.recv(1024).decode()
        pdb.set_trace()
        print('recv: ', recv_str)
        if recv_str == 'exit':
            break
        recv_dict = json.loads(recv_str)

        if 'fun' not in recv_dict:
            print('fun not in recv_dict')
            continue

        ret = eval(recv_dict['fun'] + '()')
        message_dict = {
            'fun': recv_dict['fun'],
            'ret': ret
        }
        message_json = json.dumps(message_dict)
        client.send(message_json.encode())


state1_times = 0
state2_times = 0


def state1():
    global state1_times
    print('state1')
    state1_times += 1
    if state1_times > 2:
        return state2
    return state1


def state2():
    global state2_times
    print('state2')
    state2_times += 1
    if state2_times > 1:
        return state3
    return state2


def state3():
    print('state3')
    fsm.stop()
    return state3


def fsm_test():
    fsm.addState(state1)
    fsm.addState(state2)
    fsm.addState(state3)
    fsm.start(state1)


def wifi_init_res() -> bool:
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)
    wlan.connect('CU_ugJz', '16643685017')

    for i in range(10):
        if wlan.isconnected():
            print('wifi connected')
            return True
        time.sleep(1)
        print('wifi connecting...', i)
    return False


def state_connect():
    res = wifi_init_res()
    if res:
        return state_upload
    return state_connect


def socket_connect():
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client.connect(('192.168.1.5', 8080))
    print('socket connected')
    client.send('hello'.encode())
    return client


def upload_task(aht, client):
    temp, humi = aht.read()
    print('upload_task: temp: ', temp, ' humi: ', humi)
    message_dict = {'temp': temp, 'humi': humi}
    message_json = json.dumps(message_dict)
    client.send(message_json.encode())
    return state_upload


def state_upload():
    print('state_upload')
    client = socket_connect()
    aht = aht20.AHT20()
    eventloop.start_new_task_periodic(
        upload_task, (aht, client), period_ms=5000, task_name='upload_task')
    return state_idle


g_app1_stop = False
g_app1_restart_task = False


def state_idle():
    global g_app1_stop, g_app1_restart_task
    if g_app1_stop:
        g_app1_stop = False
        eventloop.remove_task('upload_task')
        fsm.stop()
        return state_idle
    if g_app1_restart_task:
        g_app1_restart_task = False
        eventloop.remove_task('upload_task')
        return state_upload
    return state_idle


def app1():
    fsm.addState(state_connect, 'state_connect')
    fsm.addState(state_upload, 'state_upload')
    fsm.addState(state_idle, 'state_idle')
    fsm.start(state_connect)


def app1_stop():
    global g_app1_stop
    g_app1_stop = True


def app1_restart_task():
    global g_app1_restart_task
    g_app1_restart_task = True


def modbus_init():
    uart = machine.UART()
    uart.setId(1)
    uart.setPinRX("P17")
    uart.setPinTX("P18")
    uart.setBaudRate(9600)
    uart.enable()
    mb = modbus.ModBusRTU(uart=uart)
    return mb


def callback0(evt):
    print("py0 cb: %s-qos:%d-->>%s" % (evt.topic, evt.qos, evt.msg))


def mqtt_init():
    wifi_init()
    client = mqtt.MQTT('192.168.1.5', port=1883,
                       clinetID='clientid', username='name_', password='passwd_')
    print("connect ret:", client.connect())
    _ = client.setKeepAlive(5)
    ret = client.subscribe('pikapy', callback0, 0)
    print("subscribe ret:%d" % ret)
    print('listSubscribeTopic out', client.listSubscribeTopic())
    return client
